package edu.cmu.cs211.snake.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;

import javax.swing.JPanel;
import javax.swing.Timer;

public class SnakePanel extends JPanel {
	private static final long serialVersionUID = 6366150138501154425L;

	public static final int SQUARE_SIZE = 10;

	private boolean waitingforstart = true, gameover = false;

	private transient Game game;
	
	private SnakeBot snakeBot;
	private boolean usingBot = true;

	private Timer timer = new Timer (100, new ActionListener () {
		public void actionPerformed (ActionEvent e)
		{
			timer.setDelay (game.getUpdateSpeed ());
			game.tick ();
			if( usingBot )
				snakeBot.generateMove();			
			if (game.isGameOver ())
				gameover = waitingforstart = true;
			repaint ();
		}
	});

	public KeyListener getKeyListener ()
	{
		return new KeyAdapter () {
			@Override
			public void keyPressed (KeyEvent event)
			{
				if(waitingforstart) {
					newGame();
					return;
				}
				
				if( game == null ) {
					return;
				}
				
				switch (event.getKeyCode ())
				{
				case KeyEvent.VK_UP:
				    game.getSnake().up();
				    usingBot = false;
					break;
				case KeyEvent.VK_DOWN:
					game.getSnake().down();
				    usingBot = false;
					break;
				case KeyEvent.VK_LEFT:
					game.getSnake().left();
				    usingBot = false;
					break;
				case KeyEvent.VK_RIGHT:
					game.getSnake().right();
				    usingBot = false;
					break;
				case KeyEvent.VK_SPACE:
					usingBot = true;
					break;
				}
			}
		};
	}

	public void newGame ()
	{
		game = new Game (new Dimension (getWidth () / SQUARE_SIZE, getHeight ()
		        / SQUARE_SIZE));
		snakeBot = new SnakeBot(game);
		timer.start ();
		waitingforstart = false;
	}

	@Override
	public void paintComponent (Graphics g)
	{
		super.paintComponent (g);
		Graphics2D g2 = (Graphics2D) g;

		g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
		        RenderingHints.VALUE_ANTIALIAS_ON);

		if (waitingforstart || game == null) {
			// FIXME: how do I center text here?
			if (gameover == true) {
			    if (game != null)
                    g.drawString ("Your score was: " + game.getPoints (), 0, 12);
				g.drawString ("Game Over!", getWidth () / 3, getHeight () / 4);
			}
			
			int w = getWidth() / 4;
			int h = getHeight() / 3;
			
			g.drawString ("Controls", w, h += 15);
			g.drawString ("", w, h += 15);
			g.drawString ("(any key): Start a game from this screen", w, h += 15);
			g.drawString ("Space    : Toggle control to the snake bot", w, h += 15);
			g.drawString ("Left       : Toggle control to human and move left", w, h += 15);
			g.drawString ("Right     : Toggle control to human and move right", w, h += 15);
			g.drawString ("Up         : Toggle control to human and move up", w, h += 15);
			g.drawString ("Down     : Toggle control to human and move down", w, h += 15);
			return;
		}

		g.clearRect (0, 0, getWidth (), getHeight ());

		// draw snake
		g.setColor (Color.RED);
		Iterator<Point> itr = game.getSnake ().getPoints ().iterator ();
		while (itr.hasNext ()) {
			Point p = itr.next ();
			g.fillOval (p.x * SQUARE_SIZE, p.y * SQUARE_SIZE, SQUARE_SIZE,
			        SQUARE_SIZE);
		}
		// draw food
		g.setColor (Color.BLUE);

		itr = game.getFoodManager ().getFoodLocations ().iterator ();
		while (itr.hasNext ()) {
			Point p = (Point) itr.next ();
			g.fillRect (p.x * SQUARE_SIZE, p.y * SQUARE_SIZE, SQUARE_SIZE,
			        SQUARE_SIZE);
		}

		g.drawString ("Score: " + game.getPoints (), 0, 12);
	}
}
